package com.pp.ent.base.concurrent;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;

/**
 * 封装一个全局的ExecutorService线程池
 * <p>
 * Created by dengqu on 2016/11/9.
 * Copyright (c) 2016 Xunlei. All rights reserved.
 *
 * @author dengqu
 * @since 2016/11/9
 */
public abstract class XLThreadPool {

    private static ExecutorService sExecutorService = Executors.newCachedThreadPool();

    public static ExecutorService getExecutorService() {
        return sExecutorService;
    }

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the {@code Executor} implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     *                                    accepted for execution
     * @throws NullPointerException       if command is null
     */
    public static void execute(Runnable command) {
        sExecutorService.execute(command);
    }

    /**
     * Submits a value-returning task for execution and returns a
     * Future representing the pending results of the task. The
     * Future's {@code get} method will return the task's result upon
     * successful completion.
     * <p>
     * <p>
     * If you would like to immediately block waiting
     * for a task, you can use constructions of the form
     * {@code result = exec.submit(aCallable).get();}
     * <p>
     * <p>Note: The {@link Executors} class includes a set of methods
     * that can convert some other common closure-like objects,
     * for example, {@link java.security.PrivilegedAction} to
     * {@link Callable} form so they can be submitted.
     *
     * @param task the task to submit
     * @return a Future representing pending completion of the task
     * @throws RejectedExecutionException if the task cannot be
     *                                    scheduled for execution
     * @throws NullPointerException       if the task is null
     */
    public static <T> Future<T> submit(Callable<T> task) {
        return sExecutorService.submit(task);
    }

    /**
     * Submits a Runnable task for execution and returns a Future
     * representing that task. The Future's {@code get} method will
     * return the given result upon successful completion.
     *
     * @param task   the task to submit
     * @param result the result to return
     * @return a Future representing pending completion of the task
     * @throws RejectedExecutionException if the task cannot be
     *                                    scheduled for execution
     * @throws NullPointerException       if the task is null
     */
    public static <T> Future<T> submit(Runnable task, T result) {
        return sExecutorService.submit(task, result);
    }

    /**
     * Submits a Runnable task for execution and returns a Future
     * representing that task. The Future's {@code get} method will
     * return {@code null} upon <em>successful</em> completion.
     *
     * @param task the task to submit
     * @return a Future representing pending completion of the task
     * @throws RejectedExecutionException if the task cannot be
     *                                    scheduled for execution
     * @throws NullPointerException       if the task is null
     */
    public static Future<?> submit(Runnable task) {
        return sExecutorService.submit(task);
    }


    /**
     * 带有监听结果返回的
     *
     * @param task
     */
    public static void sendCommand(XLCommand task) {
       sendCommand(task,null);
    }

    /**
     * 带有监听结果返回的
     *
     * @param task
     * @param xlCommandListener
     */
    public static void sendCommand(XLCommand task, XLCommandListener xlCommandListener) {
        if (task != null && xlCommandListener != null) {
            task.setXlCommandResponse(xlCommandListener);
        }
        sExecutorService.submit(task);
    }
}
